package com.zf.jdk_new;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * jdk9新特性正式版：
 * - 模块化
 * - 集合工厂方法
 * - Stream新API以及Optional的新API
 * - 接口私有方法
 */
public class Jdk9Release {
    public static void main(String[] args) {
        testCollection();
        System.out.println("=================");
        testNewStreamApi();
        System.out.println("=================");
        testPrivateInterfaceMethod();
    }

    /**
     * 模块化
     */
    public static void testModule() {
        // 在项目中新建 module-info.java 文件，指定模块名

    }

    /**
     * 集合 新增一些工厂方法用来 创建不可变集合，不可变集合一旦创建就不能再新增、修改、移除元素，只能查询。
     * 使用 of 方法创建集合消耗更少的系统资源
     */
    public static void testCollection() {
        // List.of 创建不可变list，不能传递 null
        List<Integer> integerList = List.of(1, 2, 3);
        List<Integer> integerList2 = List.of(1, 2, 3);
        System.out.println(integerList);
        System.out.println(integerList2 == integerList); // false

        // Set.of 创建不可变set，不能传递 null，不能传递重复元素
        Set<Integer> integerSet = Set.of(1, 2, 3);
        System.out.println(integerSet);

        // Map.of 创建不可变map，key和value都不能传递 null，不能传递重复的key
        Map<String, Object> map1 = Map.of("name", "李四", "age", 22);
        System.out.println(map1);
        // Map.ofEntries 创建不可变map，key和value都不能传递 null，不能传递重复的key
        Map<String, Object> map2 = Map.ofEntries(Map.entry("name", "张三"), Map.entry("age", 55));
        System.out.println(map2);
    }

    /**
     * 新的 stream api：
     * Stream.takeWhile(),
     * Stream.dropWhile(),
     * Stream.ofNullable(),
     * Stream.iterate(),
     * Optional.stream()
     */
    public static void testNewStreamApi() {
        List<Integer> list = List.of(1, 2, 4, 6, 3, 0);
        // takeWhile从头开始提取数据，一旦遇到不满足条件的立刻停止提取，保留之前的数据，之后的数据被丢弃。
        // 从头开始提取数据，遇到小于 3 的数据就停止提取
        List<Integer> res1 = list.stream().takeWhile(item -> item < 3).collect(Collectors.toList());
        System.out.println(res1); //[1, 2]

        // dropWhile从头开始丢弃数据，满足条件就一直丢弃，一旦遇到不满足条件的时候立即停止丢弃，然后只保留后面的数据
        // 从头开始丢弃数据，遇到不满足条件（>=4）时，立刻停止丢弃，保留之后的数据
        List<Integer> res2 = list.stream().dropWhile(item -> item < 4).collect(Collectors.toList());
        System.out.println(res2); // [4, 6, 3, 0]

        // 数据最好是按照创建的顺序存储，比如List，如果是Set则不知道创建Set后数据的顺序，
        // takeWhile(), dropWhile() 无法判断结果
        Set<Integer> set = Set.of(1, 2, 4, 6, 3, 0);
        System.out.println(set);
        // Set中不知道数据的具体顺序，所以不能判断takeWhile和dropWhile的结果
        List<Integer> res3 = set.stream().takeWhile(item -> item <= 3).collect(Collectors.toList());
        System.out.println(res3); // 无法确定结果


        // of 方法不会过滤null，对于方法引用会造成空指针异常
        Stream.of(1, null, null).forEach(item -> System.out.println(item));
        // ofNullable 支持传入 null 创建stream，如果是 null，则会过滤null后创建一个空的stream
        Stream.ofNullable(null).forEach(System.out::println);

        // 生成一个流，三个参数：起始值、继续生成下一个元素的条件（不满足就停止生成）、下一个元素的生成方式
        List<Integer> res4 = Stream.iterate(1, item -> item < 3, item -> item + 1).collect(Collectors.toList());
        System.out.println(res4); //[1, 2]


        // Optional.stream() 生成流，如果 Optional的value是 null，就生成一个空的流
        Optional<Object> optional = Optional.ofNullable(null);
        List<Object> res5 = optional.stream().collect(Collectors.toList());
        System.out.println(res5); // []

    }

    /**
     * 接口私有方法
     */
    public static void testPrivateInterfaceMethod() {
        Student student = new Student();
        student.printAge();
    }

    interface Person {
        default void printAge() {
            System.out.println(getAge());
        }

        // 私有方法，可以将接口中的公共逻辑抽取成私有方法
        private int getAge() {
            return 22;
        }
    }

    static class Student implements Person {
    }

}

